package com.suxin.logger.handler;

import com.suxin.logger.LogRecord;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author Tang
 * @classname AsyncFileHandler
 * @description [  ]
 * @date 2022/4/28 11:28
 */
public class AsyncFileHandler extends FileHandler {

    private static Integer DEFAULT_MAX_RECORDS = 1000;
    private static Integer DEFAULT_LOG_SLEEP_TIME = 1000;

    protected static LinkedBlockingQueue<LogEntry> queue = new LinkedBlockingQueue<>(DEFAULT_MAX_RECORDS);

    protected static LogThread logThread = new LogThread();

    static {
        logThread.start();
    }

    @Override
    public void publish(LogRecord lr) {
        LogEntry logEntry = new LogEntry(lr, this);
        try {
            queue.put(logEntry);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void publishInternal(LogRecord lr) {
        super.publish(lr);
    }

    protected static class LogThread extends Thread {

        public LogThread() {
            this.setDaemon(true);
            this.setName("AsyncFileHandlerWriter-");
        }

        @Override
        public void run() {
            try {
                LogEntry logEntry = queue.poll(DEFAULT_LOG_SLEEP_TIME, TimeUnit.MILLISECONDS);
                if (logEntry != null) {
                    logEntry.flush();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    protected static class LogEntry {

        private LogRecord logRecord;

        private AsyncFileHandler handler;

        public LogEntry(LogRecord logRecord, AsyncFileHandler handler) {
            this.logRecord = logRecord;
            this.handler = handler;
        }

        public void flush() {
            this.handler.publishInternal(logRecord);
        }
    }

}